/**
 * 
 */
package com.mc.tencentyun;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.RandomStringUtils;

import com.alibaba.fastjson.JSON;
import com.mc.log.ThisProjectLog;
import com.mc.parameter.Parameter;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.exception.CosServiceException;
import com.qcloud.cos.exception.MultiObjectDeleteException;
import com.qcloud.cos.exception.MultiObjectDeleteException.DeleteError;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.Bucket;
import com.qcloud.cos.model.COSObjectSummary;
import com.qcloud.cos.model.DeleteObjectsRequest;
import com.qcloud.cos.model.DeleteObjectsRequest.KeyVersion;
import com.qcloud.cos.model.DeleteObjectsResult;
import com.qcloud.cos.model.DeleteObjectsResult.DeletedObject;
import com.qcloud.cos.model.GetObjectRequest;
import com.qcloud.cos.model.ListObjectsRequest;
import com.qcloud.cos.model.ObjectListing;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.region.Region;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;

/**
 * 文件管理
 * 对象存储 COS
 * 
 * @author w.weizhen
 *
 */
public class BucketTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        goGet();
        
//        goDel();
        
    }
    
    //查询信息
    private static void goGet()
    {
        // 1 初始化用户身份信息（secretId, secretKey）。
        // SECRETID 和 SECRETKEY 请登录访问管理控制台 https://console.cloud.tencent.com/cam/capi 进行查看和管理
        COSCredentials cred = new BasicCOSCredentials("AKIDFNKWu66wa8c1JH5gvyBKuLkyYuDKH4e3", "c4K0UmtoYYN1awMf4MVUHcWDlIdowrZ6");
        // 2 设置 bucket 的地域, COS 地域的简称请参见 https://cloud.tencent.com/document/product/436/6224
        // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
        Region region = new Region("ap-nanjing");
        ClientConfig clientConfig = new ClientConfig(region);
        // 这里建议设置使用 https 协议
        // 从 5.6.54 版本开始，默认使用了 https
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 3 生成 cos 客户端。
        COSClient cosClient = new COSClient(cred, clientConfig);
        
        String bucket = "fxczf-1321690287"; //存储桶名称，格式：BucketName-APPID
        
//        //创建存储桶
//        CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucket);
//        // 设置 bucket 的权限为 Private(私有读写)、其他可选有 PublicRead（公有读私有写）、PublicReadWrite（公有读写）
//        createBucketRequest.setCannedAcl(CannedAccessControlList.Private);
//        try{
//            Bucket bucketResult = cosClient.createBucket(createBucketRequest);
//        } catch (CosServiceException serverException) {
//            serverException.printStackTrace();
//        } catch (CosClientException clientException) {
//            clientException.printStackTrace();
//        }
        
        //查询存储桶列表
        List<Bucket> buckets = cosClient.listBuckets();
        //输入到日志
        log("[buckets]" + JSON.toJSONString(buckets));
//        for (Bucket bucketElement : buckets) {
//            System.out.println("Bucket: " + JSON.toJSONString(bucketElement));
//        }
        
        //查询对象列表
        // Bucket 的命名格式为 BucketName-APPID ，此处填写的存储桶名称必须为此格式
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
        // 设置 bucket 名称
        listObjectsRequest.setBucketName(bucket);
        // prefix 表示列出的 object 的 key 以 prefix 开始
        //设置为空字符,则查询所有的文件,设置某一个
        listObjectsRequest.setPrefix("");
        // deliter 表示分隔符, 设置为/表示列出当前目录下的 object, 设置为空表示列出所有的 object
//        listObjectsRequest.setDelimiter("/");
        // 设置最大遍历出多少个对象, 一次 listobject 最大支持1000
        listObjectsRequest.setMaxKeys(1000);
        
        ObjectListing objectListing = null;
        do {
            try {
                objectListing = cosClient.listObjects(listObjectsRequest);
            } catch (CosServiceException e) {
                e.printStackTrace();
                return;
            } catch (CosClientException e) {
                e.printStackTrace();
                return;
            }
            //输入到日志
            log("[objectListing]" + JSON.toJSONString(objectListing));
            // object summary 表示所有列出的 object 列表
            // 文件列表
            List<COSObjectSummary> cosObjectSummaries = objectListing.getObjectSummaries();
            //输入到日志
            log("[cosObjectSummaries]" + JSON.toJSONString(cosObjectSummaries));
            for (COSObjectSummary cosObjectSummary : cosObjectSummaries) {
//                // 文件的路径 key
//                String key = cosObjectSummary.getKey();
//                // 文件的 etag
//                String etag = cosObjectSummary.getETag();
//                // 文件的长度
//                long fileSize = cosObjectSummary.getSize();
//                // 文件最后修改时间,即文件生成时间
//                Date lastModified = cosObjectSummary.getLastModified();
//                // 文件的存储类型
//                String storageClasses = cosObjectSummary.getStorageClass();
                
                System.out.println("COSObjectSummary: " + JSON.toJSONString(cosObjectSummary));
                
                //下载文件
                // 指定文件在 COS 上的路径，即对象键。例如对象键为 folder/picture.jpg，则表示下载的文件 picture.jpg 在 folder 路径下
                String key = cosObjectSummary.getKey();
                // 方法2 下载文件到本地的路径，例如 把文件下载到本地的 /path/to/路径下的localFile文件中
                String outputFilePath = Parameter.data_path + "tencentyun" + File.separator + cosObjectSummary.getLastModified().getTime() + "_" + RandomStringUtils.random(15, "0123456789") + ".mp4";
                File downFile = new File(outputFilePath);
                GetObjectRequest getObjectRequest = new GetObjectRequest(bucket, key);
                ObjectMetadata downObjectMeta = cosClient.getObject(getObjectRequest, downFile);
                System.out.println("downObjectMeta: " + JSON.toJSONString(downObjectMeta));
                
                //输入到日志
                log("[downObjectMeta]" + JSON.toJSONString(downObjectMeta));
                //查询对象元数据
                //并没有游泳信息
                ObjectMetadata objectMetadata = cosClient.getObjectMetadata(bucket, cosObjectSummary.getKey());
                System.out.println("objectMetadata: " + JSON.toJSONString(objectMetadata));
                
            }
            
            String nextMarker = objectListing.getNextMarker();
            listObjectsRequest.setMarker(nextMarker);
        } while (objectListing.isTruncated());
        
        
        
//        //下载文件
//        // 指定文件在 COS 上的路径，即对象键。例如对象键为 folder/picture.jpg，则表示下载的文件 picture.jpg 在 folder 路径下
//        String key = "D0xIP9pRsgK3uFzJdIDpnnrWaUeJwFIfPJMf1rFuW-V8muIw+Vm6hUEJrvBZcaDTmIRXVWwA/1600007938_8888__UserId_s_dXNlcl9i__UserId_e_main.mp4";
//        // 方法2 下载文件到本地的路径，例如 把文件下载到本地的 /path/to/路径下的localFile文件中
//        String outputFilePath = Parameter.data_path + "tencentyun" + File.separator + "8d002fd34120289e7b18d8c38134c965.mp4";
//        File downFile = new File(outputFilePath);
//        GetObjectRequest getObjectRequest = new GetObjectRequest(bucket, key);
//        ObjectMetadata downObjectMeta = cosClient.getObject(getObjectRequest, downFile);
        
        
//        //删除文件
//        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucket);
//        // 设置要删除的key列表, 最多一次删除1000个
//        ArrayList<KeyVersion> keyList = new ArrayList<>();
//        // 传入要删除的文件名
//        // 注意文件名不允许以正斜线/或者反斜线\开头，例如：
//        // 存储桶目录下有a/b/c.txt文件，如果要删除，只能是 keyList.add(new KeyVersion("a/b/c.txt")), 若使用 keyList.add(new KeyVersion("/a/b/c.txt"))会导致删除不成功
//        keyList.add(new KeyVersion("prefix/D0xLTkxRsgbjdGLPdIFHmKYa1orJlTYfMMMf1rFuW-V8muIw+fX7+FJw8do+99jtxgWCNbsA/1600007938_8888__UserId_s_dXNlcl9h__UserId_e_main.mp4"));
//        keyList.add(new KeyVersion("prefix/D0xLTkxRsgbjdGLPdIFHmKYa1orJlTYfMMMf1rFuW-V8muIw+fX7+FJw8do+99jtxgWCNbsA/1600007938_8888__UserId_s_dXNlcl9i__UserId_e_main.mp4"));
//        deleteObjectsRequest.setKeys(keyList);
//        
//        try {
//            DeleteObjectsResult deleteObjectsResult = cosClient.deleteObjects(deleteObjectsRequest);
//            List<DeletedObject> deleteObjectResultArray = deleteObjectsResult.getDeletedObjects();
//            System.out.println("deleteObjectResultArray: " + JSON.toJSONString(deleteObjectResultArray));
//            //输入到日志
//            log("[deleteObjectResultArray]" + JSON.toJSONString(deleteObjectResultArray));
//        } catch (MultiObjectDeleteException mde) {
//            // 如果部分删除成功部分失败, 返回 MultiObjectDeleteException
//            List<DeletedObject> deleteObjects = mde.getDeletedObjects();
//            List<DeleteError> deleteErrors = mde.getErrors();
//            
//            System.out.println("deleteObjects: " + JSON.toJSONString(deleteObjects));
//            System.out.println("deleteErrors: " + JSON.toJSONString(deleteErrors));
//            //输入到日志
//            log("[deleteObjects]" + JSON.toJSONString(deleteObjects));
//            log("[deleteErrors]" + JSON.toJSONString(deleteErrors));
//        } catch (CosServiceException e) {
//            e.printStackTrace();
//        } catch (CosClientException e) {
//            e.printStackTrace();
//        }
        
        // 关闭客户端(关闭后台线程)
        cosClient.shutdown();
        
    }
    
    //删除数据
    private static void goDel()
    {
        
        // 设置用户身份信息。
        // SECRETID 和 SECRETKEY 请登录访问管理控制台 https://console.cloud.tencent.com/cam/capi 进行查看和管理
        COSCredentials cred = new BasicCOSCredentials("AKIDFNKWu66wa8c1JH5gvyBKuLkyYuDKH4e3", "c4K0UmtoYYN1awMf4MVUHcWDlIdowrZ6");
        
        // ClientConfig 中包含了后续请求 COS 的客户端设置：
        ClientConfig clientConfig = new ClientConfig();
        
        // 设置 bucket 的地域
        // COS_REGION 请参见 https://cloud.tencent.com/document/product/436/6224
        clientConfig.setRegion(new Region("ap-nanjing"));
        
        // 设置请求协议, http 或者 https
        // 5.6.53 及更低的版本，建议设置使用 https 协议
        // 5.6.54 及更高版本，默认使用了 https
        clientConfig.setHttpProtocol(HttpProtocol.https);
        // 调用 COS 接口之前必须保证本进程存在一个 COSClient 实例，如果没有则创建
        // 详细代码参见本页：简单操作 -> 创建 COSClient
        // 3 生成 cos 客户端。
        COSClient cosClient = new COSClient(cred, clientConfig);
        
        
//        // 以下的设置，是可选的：
//        
//        // 设置 socket 读取超时，默认 30s
//        clientConfig.setSocketTimeout(30*1000);
//        // 设置建立连接超时，默认 30s
//        clientConfig.setConnectionTimeout(30*1000);
//        
//        // 如果需要的话，设置 http 代理，ip 以及 port
//        clientConfig.setHttpProxyIp("httpProxyIp");
//        clientConfig.setHttpProxyPort(80);
        
        
        // 存储桶的命名格式为 BucketName-APPID，此处填写的存储桶名称必须为此格式
        String bucket = "fxczf-1321690287"; //存储桶名称，格式：BucketName-APPID
        
        DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucket);
        // 设置要删除的key列表, 最多一次删除1000个
        ArrayList<KeyVersion> keyList = new ArrayList<>();
        // 传入要删除的文件名
        // 注意文件名不允许以正斜线/或者反斜线\开头，例如：
        // 存储桶目录下有a/b/c.txt文件，如果要删除，只能是 keyList.add(new KeyVersion("a/b/c.txt")), 若使用 keyList.add(new KeyVersion("/a/b/c.txt"))会导致删除不成功
        keyList.add(new KeyVersion("prefix/D0xLTkxRsgbjdGLPdIFHmKYa1orJlTYfMMMf1rFuW-V8muIw+fX7+FJw8do+99jtxgWCNbsA/1600007938_8888__UserId_s_dXNlcl9h__UserId_e_main.mp4"));
        keyList.add(new KeyVersion("prefix/D0xLTkxRsgbjdGLPdIFHmKYa1orJlTYfMMMf1rFuW-V8muIw+fX7+FJw8do+99jtxgWCNbsA/1600007938_8888__UserId_s_dXNlcl9i__UserId_e_main.mp4"));
        deleteObjectsRequest.setKeys(keyList);
        
        try {
            DeleteObjectsResult deleteObjectsResult = cosClient.deleteObjects(deleteObjectsRequest);
            List<DeletedObject> deleteObjectResultArray = deleteObjectsResult.getDeletedObjects();
            //输入到日志
            log("[deleteObjectResultArray]" + JSON.toJSONString(deleteObjectResultArray));
        } catch (MultiObjectDeleteException mde) {
            // 如果部分删除成功部分失败, 返回 MultiObjectDeleteException
            List<DeletedObject> deleteObjects = mde.getDeletedObjects();
            List<DeleteError> deleteErrors = mde.getErrors();
            //输入到日志
            log("[deleteObjects]" + JSON.toJSONString(deleteObjects));
            log("[deleteErrors]" + JSON.toJSONString(deleteErrors));
        } catch (CosServiceException e) {
            e.printStackTrace();
        } catch (CosClientException e) {
            e.printStackTrace();
        }
        
        // 确认本进程不再使用 cosClient 实例之后，关闭即可
        cosClient.shutdown();
    }
    
    //生成日志
    private static void log(String log)
    {
    	//输入到日志
        String path = Parameter.data_path + "tencentyun" + File.separator + DateUtil.today() + "_BucketTest.log";
        ThisProjectLog.createLog(path, Arrays.asList(DateUtil.now() + "  :  " + log));
    }
}